<script lang="ts" setup>
import {ref, onMounted, markRaw} from 'vue'
import {
  addDataSourceApi,
  pageDataSourceApi,
  updateDataSourceApi,
  deleteDataSourceApi,
  dataVerificationApi,
  getSupportTypeApi
} from '@/api/data-source'
import {
  DataSourceListDTO,
  DataSourceQuery,
  DataSourceUpdateDTO,
  SupportType
} from "@/api/data-source/models";
import {Delete, Edit, Plus, Search} from "@element-plus/icons-vue";
import {OpenDialogInfo} from "@/types/baseInterface";
import {ElMessage, ElMessageBox, FormInstance} from "element-plus";
import {TipInfo} from "@/api/types/commonTypes";

const tableData = ref<DataSourceListDTO[]>([]) // 使用 ref 来存储动态数据
const totalQuantity = ref<number>(0)//总条数
const currentPage = ref<number>(1)//当前页
const pageSize = ref<number>(10) // 设置默认的分页大小
const detailData = ref<DataSourceListDTO>({} as DataSourceListDTO) // 存储当前行的详情数据
const openDialog = ref<OpenDialogInfo>({openState: false} as OpenDialogInfo)//是否打开添加对话框对话框
const typeList = ref<SupportType[]>([])
const detailDataValid = ref<FormInstance>()
const searchQuery = ref<DataSourceQuery>({size: 10, current: 1, name: '', type: '', contentType: ''})

//验证数据
async function verificationConfiguration(formEl: FormInstance | undefined): Promise<boolean> {
  if (!formEl) return false
  return formEl.validate().then(() => dataVerificationApi(detailData.value).then(res => {
    if (res.data.code == 200) {
      ElMessage({
        type: 'success',
        message: "验证成功！",
      })
      return true
    } else return false
  }))
}

// 加载数据的函数
function loadPage(params: DataSourceQuery) {
  pageDataSourceApi(params).then((response) => {
    const data = response.data.data;
    currentPage.value = data.current
    totalQuantity.value = data.total
    tableData.value = data.records // 假设响应数据结构包含在 records 属性中
  })
}

// 打开详情对话框并传递数据
const openDetailDialog = (rowData: DataSourceListDTO) => {
  detailData.value = rowData; // 将当前行的数据传递给 detailData
  openDialog.value = {disabled: true, openState: true, isAdd: false, title: "数据源详情"}
}

//打开设置对话框
const editFunc = (data: DataSourceUpdateDTO) => {
  Object.assign(detailData.value, data)// 将当前行的数据传递给 detailData
  openDialog.value = {
    disabled: false,//不禁用输入
    openState: true,//打开对话框
    isAdd: false,
    title: "修改数据源", //名称
  }
}

//修改数据
function editDataSource(formEl: FormInstance | undefined) {
  if (!formEl) return
  formEl.validate().then(() => {
    updateDataSourceApi(detailData.value).then(() => {
      ElMessage({
        type: 'success',
        message: "修改成功！",
      })
    }).catch((err) => {
      ElMessage.error("修改失败:" + err.data)
    })
    loadPage({current: currentPage.value, size: pageSize.value}); // 传递默认的分页参数
    //关闭对话框
    handleCloseFun();
  })
}

//打开删除对话框
const deleteFunc = (id: string) => {
  ElMessageBox.confirm(
      '确认删除当前行?',
      '删除',
      {
        center: true,
        draggable: true,
        confirmButtonText: '确认',
        cancelButtonText: '返回',
        type: 'warning',
        icon: markRaw(Delete)
      }
  ).then(() => {
    //提交请求
    deleteDataSourceApi(id).then(() => {
      ElMessage({
        type: 'success',
        message: "删除成功！",
      })
      //重新加载页数据
      loadPage({current: currentPage.value, size: pageSize.value}); // 传递默认的分页参数
    })
  })
}

//添加模板数据
function addDataSourceFun() {
  // 添加弹窗打开前把数据清理了
  openDialog.value = {
    disabled: false,//是否禁用编辑
    openState: true,//对话框打开状态
    isAdd: true,//是否为添加
    title: "添加数据源",
  }
}

//处理关闭的对话框
function handleCloseFun() {
  //关闭对话框
  openDialog.value = {
    openState: false, //关闭对话框
  } as OpenDialogInfo
}

//添加数据源
function addDataSource(formEl: FormInstance | undefined) {
  if (!formEl) return
  formEl.validate().then(() => {
    addDataSourceApi(detailData.value).then(resp => {
      if (resp.data.code === 200) {
        ElMessage({
          type: 'success',
          message: "添加成功！",
        })
        loadPage({current: currentPage.value, size: pageSize.value}); // 传递默认的分页参数
        //清理表单
        detailData.value = {} as DataSourceListDTO
        //关闭对话框
        handleCloseFun();
      }
    })
  })
}

//获取数据源内容类型
function getContentType(type: string | undefined): TipInfo[] {
  //编写代码从typeList中查找对应的contentType，查找条件为type与typeList.type.code相同
  return typeList.value.find(item => item.type.code === type)?.contentType || []
}

// 初始化时加载数据
onMounted(() => {
  getSupportTypeApi().then(resp => {
    typeList.value = resp.data.data
  })
  loadPage({current: currentPage.value, size: pageSize.value}); // 传递默认的分页参数
})

// 更新每页显示数据条数的处理函数
const handleSizeChange = (val: number) => {
  pageSize.value = val; // 更新 pageSize
  currentPage.value = 1; // 重置为第一页
  loadPage({current: currentPage.value, size: pageSize.value}) // 重新加载数据
}

// 更新当前页的处理函数
const handleCurrentChange = (val: number) => {
  currentPage.value = val; // 更新当前页
  loadPage({current: currentPage.value, size: pageSize.value}) // 重新加载数据
}

//处理搜索
function searchFun() {
  loadPage({...searchQuery.value, current: currentPage.value, size: pageSize.value}); // 传递默认的分页参数
}

</script>

<template>
  <div style="position: absolute;top: 50px;inset: 45px 20px 0;">
    <div style="display: flex; justify-content: space-between; align-items: center; margin: 10px 20px;">
      <div style="flex: 0 0 auto">
        <el-button @click="addDataSourceFun" :icon="Plus" circle/>
      </div>
      <div style="flex: 0 0 auto; display: flex; gap: 8px; align-items: center">
        名称：
        <el-input v-model="searchQuery.name" style="width: 200px" placeholder="输入名称搜索"/>
        类型：
        <el-select
            v-model="searchQuery.type"
            placeholder="请选择类型"
            size="large"
            clearable
            style="width: 200px"
        >
          <el-option
              v-for="(t,ti) in typeList"
              :key="ti"
              :label="t.type.tip"
              :value="t.type.code"
          />
        </el-select>
        数据类型：
        <el-select
            v-model="searchQuery.contentType"
            :disabled="!searchQuery.type"
            placeholder="请选择数据类型"
            size="large"
            clearable
            style="width: 200px"
        >
          <el-option
              v-for="(ct,cti) in getContentType(searchQuery.type)"
              :key="cti"
              :label="ct.tip"
              :value="ct.code"
          />
        </el-select>
        <el-button @click="searchFun" :icon="Search" circle/>
      </div>
    </div>
    <el-table :data="tableData" style="width: 100%;height: 70vh">
      <el-table-column prop="name" label="名称" width="150"/>
      <el-table-column prop="typeName" label="类型" width="100"/>
      <el-table-column prop="contentTypeName" label="数据类型"/>
      <el-table-column prop="tablePrefix" label="移除前缀"/>
      <el-table-column prop="exclusionTable" label="排除表"/>
      <el-table-column prop="createTime" label="创建时间" width="170"/>
      <el-table-column prop="updateTime" label="更新时间" width="170"/>
      <el-table-column label="操作" width="150">
        <template v-slot="scope">
          <el-button @click="openDetailDialog(scope.row)" :icon="Search" circle/>
          <el-button @click="editFunc(scope.row)" type="primary" :icon="Edit" circle/>
          <el-button @click="deleteFunc(scope.row.id)" type="danger" :icon="Delete" circle/>
        </template>
      </el-table-column>
    </el-table>
    <div class="demo-pagination-block">
      <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[1,2,4,10, 20, 40, 100, 200, 400, 1000]"
          :disabled="false"
          :background="true"
          layout="total, sizes, prev, pager, next, jumper"
          :total="totalQuantity"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
      />
    </div>
    <el-dialog
        v-model="openDialog.openState"
        :title="openDialog.title"
        width="800px"
        :before-close="handleCloseFun"
        draggable>
      <template #default>
        <el-form label-width="80px"
                 ref="detailDataValid"
                 :model="detailData">
          <el-form-item label="名称"
                        prop="name"
                        :rules="{required: true,message: '名称不能为空！'}">
            <el-input v-model="detailData.name" :disabled="openDialog.disabled"/>
          </el-form-item>
          <el-form-item label="类型"
                        prop="type"
                        :rules="{required: true,message: '类型不能为空！'}">
            <el-select
                v-model="detailData.type"
                size="large"
                :disabled="openDialog.disabled">
              <el-option
                  v-for="(t,ti) in typeList"
                  :key="ti"
                  :label="t.type.tip"
                  :value="t.type.code"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="内容类型"
                        prop="contentType"
                        :rules="{required: true,message: '数据源内容类型不能为空！'}"
                        v-if="detailData.type">
            <el-select
                v-model="detailData.contentType"
                size="large"
                :disabled="openDialog.disabled">
              <el-option
                  v-for="(ct,cti) in getContentType(detailData.type)"
                  :key="cti"
                  :label="ct.tip"
                  :value="ct.code"
              />
            </el-select>
          </el-form-item>
          <div v-if="detailData.type == 'structure'">
            <el-form-item label="url"
                          prop="url"
                          :rules="{required: true,message: 'url不能为空！'}">
              <el-input v-model="detailData.url" :disabled="openDialog.disabled"/>
            </el-form-item>
            <el-form-item label="username"
                          prop="username"
                          v-if="detailData.contentType != 'SQLite'"
                          :rules="{required: true, message: 'username不能为空！'}">
              <el-input v-model="detailData.username" :disabled="openDialog.disabled"/>
            </el-form-item>
            <el-form-item label="password"
                          prop="password"
                          v-if="detailData.contentType != 'SQLite'"
                          :rules="{required: true, message: 'password不能为空！'}">
              <el-input v-model="detailData.password" :disabled="openDialog.disabled"/>
            </el-form-item>
            <el-form-item label="表前缀">
              <el-input v-model="detailData.tablePrefix"
                        :disabled="openDialog.disabled"
                        placeholder="表前缀(多个使用英文逗号隔开)"/>
            </el-form-item>
            <el-form-item label="排除表">
              <el-input v-model="detailData.exclusionTable"
                        :disabled="openDialog.disabled"
                        placeholder="排除表(多个使用英文逗号隔开)"/>
            </el-form-item>
          </div>
          <div v-if="detailData.type == 'instance'">
            <el-form-item label="数据内容"
                          prop="content"
                          :rules="{required: true,message: '数据内容不能为空！'}">
              <el-input v-model="detailData.content"
                        type="textarea"
                        :rows="10"
                        autocomplete="off"
                        :disabled="openDialog.disabled"/>
            </el-form-item>
          </div>
        </el-form>
        <div class="dialog-footer">
          <el-button @click="handleCloseFun">取消</el-button>
          <el-button @click="verificationConfiguration(detailDataValid)"
                     :disabled="openDialog.disabled">
            测试连接/验证数据
          </el-button>
          <el-button v-if="openDialog.isAdd"
                     type="primary"
                     :disabled="openDialog.disabled"
                     @click="addDataSource(detailDataValid)">确认
          </el-button>
          <el-button v-else type="primary"
                     :disabled="openDialog.disabled"
                     @click="editDataSource(detailDataValid)">
            确认
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
